#include "App.h"
#include "Buzzer.h"
#include "Delay.h"

// 音符与索引对应表，P：休止符，L：低音，M：中音，H：高音，下划线：升半音符号#
#define L1 1
#define L2 2
#define L3 3
#define L4 4
#define L5 5
#define L6 6
#define L7 7

// 转调要改
#define N0 0
#define NX 0
#define P 0

#define M1 L1 + 7
#define M2 L2 + 7
#define M3 L3 + 7
#define M4 L4 + 7
#define M5 L5 + 7
#define M6 L6 + 7
#define M7 L7 + 7

#define N1 L1 + 7
#define N2 L2 + 7
#define N3 L3 + 7
#define N4 L4 + 7
#define N5 L5 + 7
#define N6 L6 + 7
#define N7 L7 + 7

#define H1 M1 + 7
#define H2 M2 + 7
#define H3 M3 + 7
#define H4 M4 + 7
#define H5 M5 + 7
#define H6 M6 + 7
#define H7 M7 + 7

u16 FREQS[] = {
    // 静止
    0,
    // 低音
    523 * 1, 587 * 1, 659 * 1, 698 * 1, 784 * 1, 880 * 1, 988 * 1,
    // 中音
    523 * 2, 587 * 2, 659 * 2, 698 * 2, 784 * 2, 880 * 2, 988 * 2,
    // 高音
    523 * 4, 587 * 4, 659 * 4, 698 * 4, 784 * 4, 880 * 4, 988 * 4,
    // 523 * 8, 587 * 8, 659 * 8, 698 * 8, 784 * 8, 880 * 8, 988 * 8,
    // 523 * 16, 587 * 16, 659 * 16, 698 * 16, 784 * 16, 880 * 16, 988 * 16,

};

/* 天空之城
C=4/4  一拍4个单位interval*/
u8 code Music1[] = {
    N6, N7, H1, N7, H1, H3, N7, N3, N3, N6, N5, N6, H1, N5, N0, N3, N3, N4, N3,
    N4, H1, N3, N0, H1, H1, H1, N7, N4, N4, N7, N7, N0, N6, N7, H1, N7, H1, H3,
    N7, N0, N3, N3, N6, N5, N6, H1, N5, N0, N3, N4, H1, N7, N7, H1, H2, H2, H3,
    H1, N0, H1, N7, N6, N6, N7, N5, N6, N0, H1, H2, H3, H2, H3, H5, H2, N0, N5,
    N5, H1, N7, H1, H3, H3, N0, N0, N6, N7, H1, N7, H2, H2, H1, N5, N5, N0, H4,
    H3, H2, H1, H3, H3, N0, H3, H6, H5, H5, H3, H2, H1, N0, H1, H2, H1, H2, H2,
    H5, H3, N0, H3, H6, H5, H3, H2, H1, N0, H1, H2, H1, H2, H2, N7, N6, N0,
};

u8 code durations1[] = {
    2, 2, 6,  2, 4, 4, 12, 2, 2, 6, 2,  4, 4, 8, 4, 2, 2, 6, 2, 2, 6, 8,
    2, 2, 2,  2, 6, 2, 4,  4, 8, 4, 2,  2, 6, 2, 4, 4, 8, 4, 2, 2, 6, 2,
    4, 4, 12, 2, 2, 4, 2,  2, 4, 4, 2,  2, 2, 4, 4, 4, 2, 2, 2, 4, 4, 8,
    4, 2, 2,  6, 2, 4, 4,  8, 4, 2, 2,  2, 2, 4, 4, 8, 4, 4, 2, 2, 4, 4,
    2, 2, 6,  2, 4, 4, 4,  4, 4, 4, 16, 8, 4, 4, 8, 4, 4, 2, 2, 4, 2, 2,
    4, 2, 2,  2, 4, 8, 4,  4, 8, 8, 2,  2, 8, 2, 2, 4, 2, 2, 2, 4, 8, 4,
};

/* 贪吃蛇大作战
  D=4/4 90 一拍8个单位interval  */
u8 code Music2[] = {
    /* 8 -4 --2 ---1   */
    // 1-1
    H1, M7, H1, M7, H1, M5, M6, H1, H3, H2, H1, H2,
    // 1-2
    H1, M7, H1, M7, H1, M6, M5, H5, H5, H5,
    // 2-1
    H1, M7, H1, M7, H1, M5, M6, H1, H3, H2, H1, H2,
    // 2-2
    H1, M7, H1, M7, H1, H3, H2, H2};

u8 code durations2[] = {
    /* 8 -4 --2 ---1   */
    // 1-1
    3, 1, 3, 1, 4, 4, 4, 3, 1, 3, 1, 4,
    // 1-2
    3, 1, 3, 1, 4, 3, 5, 3, 1, 4,
    // 2-1
    3, 1, 3, 1, 4, 4, 4, 3, 1, 3, 1, 4,
    // 2-2
    3, 1, 3, 1, 4, 3, 1, 16};

/* 不眠之夜
  E=4/4 120 一拍4个单位interval  */
u8 code Music3[] = {
    N0, N2, N3, L6, L6, L6, N1, L6, L6, N0, N3, N2, N3, L6, L6, N0, N6, N6,
    N5, N6, N6, N0, N2, N3, L6, L6, L6, N1, L6, L6, N0, N3, N2, N1, N2, N2,
    N0, N5, N5, N3, N5, N5, N0, N2, N3, L6, L6, L6, N1, L6, L6, N0, N3, N2,
    N1, N1, N1, N2, N0, N2, N1, N0, N1, L7, N0, L7, L6, N0, L6, N0, L5, L5,
    N0, L6, N0, N0, N0, L6, N1, L7, N3, N2, N5, N4, N4, N4, N3, N3, N0, N0,
    N3, N3, N2, N1, L6, N1, N2, N0, L6, N1, L7, N3, N2, N5, N4, N4, N4, N3,
    N3, N0, N0, NX, NX, NX, NX, NX, NX, N0, N3, N0, N2, N0, N1, N0, L7, N0,
    L6, L7, L7, N1, N1, L6, N0, L6, N3, N0, N2, N0, N1, N0, L7, L6, L7, L7,
    N1, N1, N0, L6, N5, N0, N4, N3, N3, N1, N1, N1, N2, N2, N1, N3, N0, N1,
    L6, N1, L6, N2, N3, N3, N2, N0, N2, N3, N3, N1, L6, N0, N3, N0, N2, N0,
    N1, N0, L7, L6, L6, L7, N1, N1, L6, N0, L6, N3, N0, N2, N0, N1, N0, L7,
    L6, L7, L7, N1, N1, L7, N0, L6, N5, N0, N4, N3, N3, N1, N1, N1, N2, N2,
    N1, N3, N0, N1, L6, N1, L6, N2, N3, N3, N2, N0, N2, N3, N3, N1, L6, N0};
u8 code durations3[] = {
    2, 2, 3, 1, 2, 2, 3, 1, 1, 1, 2, 2, 1,  1, 1, 2,  2, 2, 1, 1, 1, 1, 2, 2,
    1, 2, 2, 3, 1, 1, 1, 2, 2, 1, 1, 1, 1,  2, 2, 1,  1, 1, 1, 2, 2, 1, 2, 2,
    2, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2,  2, 2, 2,  2, 2, 2, 4, 2, 1, 1, 1,
    1, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2,  2, 2, 12, 4, 2, 1, 1, 1, 1, 2, 2,
    1, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 12, 4, 2, 1,  1, 2, 1, 1, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,  2, 2, 2,  2, 2, 2, 2, 4, 3, 1, 2,
    2, 2, 4, 2, 2, 2, 3, 1, 2, 2, 2, 1, 1,  1, 1, 4,  2, 2, 2, 2, 2, 3, 1, 2,
    2, 4, 2, 2, 2, 2, 8, 4, 2, 2, 2, 2, 2,  2, 4, 3,  1, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 4, 3, 1, 2, 2, 2, 2, 2,  2, 2, 2,  3, 1, 2, 2, 2, 1, 1, 1,
    1, 4, 2, 2, 2, 2, 2, 3, 1, 2, 2, 4, 2,  2, 2, 2,  8, 4};

u16 music1_len = sizeof(Music1) / sizeof(Music1[0]);
u16 music2_len = sizeof(Music2) / sizeof(Music2[0]);
u16 music3_len = sizeof(Music3) / sizeof(Music3[0]);

void music_play(u8* music, u8* durations, u8 interval, u16 len) {
  u8 i;

  u16 freq;
  u16 d;
  u8 note;

  for (i = 0; i < len; i++) {
    note = music[i];
    freq = FREQS[note];  // 频率
    if (freq == 0) {
      Buzzer_close();
    } else {
      Buzzer_music(freq);
    }
    // if (note == 0) {
    //   LED_down_all();
    // } else {
    //   LED_up_one(note % 7);
    // }

    d = durations[i] * interval;  // 三十二分音符音长
    while (d--)
      delay_ms(1);

    // pause
    // Buzzer_close();
    // delay_ms(1);
  }
}

void task_buzzer() _task_ TASK_BUZZER {
  u8 i;
  for (i = 0; i < 6; i++) {
    Buzzer_play(3, 50);
    os_wait2(K_TMO, 200);
  }
  os_delete_task(TASK_BUZZER);
}

void task_bgm() _task_ TASK_BGM {
  while (1) {
    music_play(Music2, durations2, 125, music2_len);
  }
}

void task_music() _task_ TASK_MUSIC {
  switch (music_menu_no) {
    case 0:
      music_play(Music1, durations1, 100, music1_len);
      break;
    case 1:
      music_play(Music3, durations3, 125, music3_len);
      break;
    default:
      break;
  }
}